<template>
  <div>
    <div class="container">
      <div class="div1" v-drag></div>
    </div>
  </div>
</template>
<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      dragAble : false
    }
  },
  directives: {
    //拖拽&&缩放指令
    drag: {
      bind: (el, binding) => {
        //绑定默认样式
        el.style.zIndex = '9';
        el.style.backgroundColor = "rgba(0,0,0,1)";
        //如果为编辑状态
        if (binding.value || binding.value === undefined) {
          //定义该元素的 top left width height
          let x, y, w, h;
          //鼠标的起始和结束坐标
          let cx_start, cy_start, cx_end, cy_end;
          //判断鼠标样式
          el.onmousemove = () => {
              el.style.cursor = "move";
          };
          el.onmousedown = e => {
            let mouse = el.style.cursor;
            //更改默认样式
            el.style.backgroundColor = "rgba(0,0,0,.5)";
            el.style.zIndex = '99';
            //对象解构赋值
            let { left: el_x, top: el_y, width: el_w, height: el_h } = window.getComputedStyle(el);
            x = el_x;
            y = el_y;
            w = el_w;
            h = el_h;
            cx_start = e.clientX;
            cy_start = e.clientY;
            //绑定移动事件
            document.onmousemove = e => {
              cx_end = e.clientX;
              cy_end = e.clientY;
              //默认左下方向配置
              let x_move = cx_end - cx_start;
              let y_move = cy_end - cy_start;
              let direct = ["left", "top"];
              let pos = [w, h];
              let move = [x_move, y_move];
              let limit = 50;
              //判断鼠标的类型进行对应的操作
              switch (mouse) {
                case "e-resize":
                  direct = ["width"];
                  pos = [w];
                  move = [x_move];
                  break;
                case "s-resize":
                  direct = ["height"];
                  pos = [h];
                  move = [y_move];
                  break;
                case "move":
                  direct = ["left", "top"];
                  pos = [x, y];
                  limit = 0;
                  break;
              }
              handle_div(direct, pos, move, limit);
            };
            //取消移动事件
            document.onmouseup = () => {
              //还原默认样式
              el.style.zIndex = '9';
              el.style.backgroundColor = "rgba(0,0,0,1)";
              document.onmousemove = null;
            };
            /**
             * 操作DOM位置和大小方法
             * @param direct 方向
             * @param pos 尺寸/坐标
             * @param move 拖动距离
             * @param limit 限定范围
             */
            function handle_div(direct, pos, move, limit) {
              for (let i = 0; i < direct.length; i++) {
                let val = parseInt(pos[i]) + move[i];
                val = val <= limit ? limit : val;
                el.style[direct[i]] = val + "px";
              }
            }
          };
        } else {
          el.style.cursor = "default";
          //移除点击事件
          el.onmousedown = null;
          el.onmousemove = null;
        }
      }
    }
  }
};
</script>

<style scoped>
.container {
  width: 100%;
  height: 500px;
  position: relative;
  border: 1px solid black;
  overflow: auto;
}
.div1 {
  height: 50px;
  width: 50px;
  border: 1px solid red;
  position: absolute;
  left: 0;
  top: 0;
}
</style>
